﻿using RndMaterialDisposalService.Attrbutes;
using RndMaterialDisposalService.Models;
using RndMaterialDisposalService.Models.Entitys;
using RndMaterialDisposalService.Repository;
using RndMaterialDisposalService.Services.Interface;
using Masuit.Tools.Core.AspNetCore;
using NPOI.POIFS.Properties;
using NPOI.SS.Formula.Functions;
using System.Text.Json;

namespace RndMaterialDisposalService.Services
{
    /// <summary>
    /// 
    /// </summary>
    [NAutowired(Lifecycle.Scoped)]
    public class DataDictionaryService : IDataDictionaryService
    {
        private AssetsManagementContext dbContext;
        private ILogger<DataDictionaryService> logger;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_dbContext"></param>
        /// <param name="logger"></param>
        public DataDictionaryService(AssetsManagementContext _dbContext, ILogger<DataDictionaryService> logger)
        {
            dbContext = _dbContext;
            this.logger = logger;   
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ConfigDictionaryModel> AddDictItem(ConfigDictionaryModel model)
        {
            await dbContext.ConfigDictionary.AddAsync(model);
            dbContext.SaveChanges();
            return model;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="name"></param>
        /// <param name="code"></param>
        /// <param name="remark"></param>
        /// <param name="Id"></param>
        /// <param name="viewType"></param>
        /// <returns></returns>
        public async Task<ConfigDictionaryModel> AddDirectory(Guid parentId, string name, string code, string remark, Guid? Id, int? funTag, string? viewType)
        {
            var model = new ConfigDictionaryModel();
            model.Id = Id ?? Guid.NewGuid();
            model.ParentId = parentId;
            model.Name = name;
            model.Code = code;
            model.Type = 1;
            model.Remark = remark;
            model.AdminViews = viewType;
            model.FunTag = funTag;
            dbContext.Set<ConfigDictionaryModel>().AddOrUpdate(t => t.Id, model);
            await dbContext.SaveChangesAsync();
            return model;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="parentId"></param>
        /// <returns></returns>
        public async Task<List<ConfigDictionaryModel>> GetDictItems(Guid parentId)
        {
            return await dbContext.ConfigDictionary.Where(x => x.ParentId == parentId && x.IsDeleted == false && x.Type == 2).OrderByDescending(p => p.CreateTime).ToListAsync();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="parentCode"></param>
        /// <returns></returns>
        public async Task<List<ConfigDictionaryModel>> GetDictItems(string parentCode)
        {
            var result = from dict1 in dbContext.ConfigDictionary
                         join dict2 in dbContext.ConfigDictionary
                         on dict1.ParentId equals dict2.Id
                         where dict2.Code == parentCode
                             && dict1.Type == 2
                             && dict1.IsDeleted == false
                             && dict1.ActiveDate <= DateTime.Now
                             && dict1.InActiveDate >= DateTime.Now
                         select dict1;
            return await result.ToListAsync();
        }

        /// <summary>
        /// 数据字典查询-标准
        /// </summary>
        /// <param name="parentCode"></param>
        /// <returns></returns>
        public async Task<List<StandardDictionaryConfigurationModel>> GetTemporaryDictItems(string parentCode)
        {
            var result = from dict1 in dbContext.StandardDictionaryConfiguration
                         join dict2 in dbContext.StandardDictionaryConfiguration
                         on dict1.ParentId equals dict2.Id
                         where dict2.Code == parentCode
                             && dict1.Type == 2
                             && dict1.IsDeleted == false
                             && dict1.ActiveDate <= DateTime.Now
                             && dict1.InActiveDate >= DateTime.Now
                         select dict1;
            return await result.ToListAsync();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="viewViews"></param>
        /// <returns></returns>
        public async Task<List<ConfigDictionaryModel>> GetDirectory(string viewViews)
        {
            return await dbContext.ConfigDictionary.Where(x => x.IsDeleted == false && x.Type == 1 && x.AdminViews == viewViews).ToListAsync();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<ConfigDictionaryModel> UpdateDictItem(ConfigDictionaryModel model)
        {
            dbContext.ConfigDictionary.Update(model);
            await dbContext.SaveChangesAsync();
            return await Task.FromResult(model);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="dictCode"></param>
        /// <returns></returns>
        public Task<bool> VerifyDictCode(Guid? parentId, string dictCode)
        {
            var query = dbContext.ConfigDictionary.Where(p => p.Code == dictCode && p.IsDeleted == false);
            if (parentId.HasValue)
            {
                query = query.Where(p => p.ParentId == parentId.Value);
            }
            return query.AnyAsync();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<int> DeleteDictItem(Guid key)
        {
            var model = await dbContext.ConfigDictionary.FirstOrDefaultAsync(p => p.Id == key);
            model!.Id = key;
            model.IsDeleted = true;
            model.ModifiedTime = DateTime.Now;
            var modifiedEntity = dbContext.Entry(model);
            modifiedEntity.State = EntityState.Modified;
            return await dbContext.SaveChangesAsync();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="EditionType"></param>
        /// <returns></returns>
        public async Task<List<StandardDictionaryConfigurationModel>> GainDictCatalogueItemList(string EditionType)
        {
            var list = await dbContext.StandardDictionaryConfiguration.Where(a => a.EditionType == EditionType && a.IsDeleted == false && a.Type == 1).ToListAsync();
            return list;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stand"></param>
        /// <returns></returns>
        public async Task<int> EditStandardDictionaryConfiguration(StandardDictionaryConfigurationModel stand)
        {
            int NumberOfAffectedRows = 0;
            if (stand != null)
            {
                var item = await dbContext.StandardDictionaryConfiguration.FirstOrDefaultAsync(a => a.Id == stand.Id);
                if (item != null)
                {
                    item.Code = stand.Code;
                    item.Name = stand.Name;
                    item.Value = stand.Value;
                    item.Value = stand.Value;
                    item.Remark = stand.Remark;
                    item.ActiveDate = stand.ActiveDate;
                    item.InActiveDate = stand.InActiveDate;
                    item.Field1 = stand.Field1;
                    item.Field2 = stand.Field2;
                    item.Field3 = stand.Field3;
                    item.Field4 = stand.Field4;
                    item.Field5 = stand.Field5;
                    item.Field6 = stand.Field6;

                    dbContext.StandardDictionaryConfiguration.Update(item);
                    NumberOfAffectedRows = await dbContext.SaveChangesAsync();
                }
            }
            return NumberOfAffectedRows;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stand"></param>
        /// <returns></returns>
        public async Task<int> AddStandardDictionaryConfiguration(StandardDictionaryConfigurationModel stand)
        {
            int NumberOfAffectedRows = 0;
            if (stand != null)
            {
                dbContext.StandardDictionaryConfiguration.Add(stand);
                NumberOfAffectedRows = await dbContext.SaveChangesAsync();
            }
            return NumberOfAffectedRows;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stand"></param>
        /// <returns></returns>
        public async Task<int> DeleteStandardDictionaryConfiguration(StandardDictionaryConfigurationModel stand)
        {
            int NumberOfAffectedRows = 0;
            if (stand != null)
            {
                var item = await dbContext.StandardDictionaryConfiguration.FirstOrDefaultAsync(a => a.Id == stand.Id);
                if (item != null)
                {
                    //dbContext.StandardDictionaryConfiguration.Remove(stand);
                    item.IsDeleted = true;
                    item.ModifiedTime = DateTime.Now;
                    var modifiedEntity = dbContext.Entry(item);
                    modifiedEntity.State = EntityState.Modified;
                    NumberOfAffectedRows = await dbContext.SaveChangesAsync();
                }
            }
            return NumberOfAffectedRows;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Code"></param>
        /// <returns></returns>
        public async Task<StandardDictionaryConfigurationModel> GetStandardDictionaryConfigurationItem(string Code)
        {
            StandardDictionaryConfigurationModel stand = new StandardDictionaryConfigurationModel();
            if (!string.IsNullOrWhiteSpace(Code))
            {
                stand = await dbContext.StandardDictionaryConfiguration.FirstOrDefaultAsync(a => a.Code == Code);
            }
            return stand;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ParentId"></param>
        /// <returns></returns>
        public async Task<List<StandardDictionaryConfigurationModel>> GetSeekStandardDictionaryConfigurationList(Guid ParentId)
        {
            List<StandardDictionaryConfigurationModel> list = new List<StandardDictionaryConfigurationModel>();
            list = await dbContext.StandardDictionaryConfiguration.Where(a => a.ParentId == ParentId && a.IsDeleted == false && a.Type == 2).ToListAsync();
            return list;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<StandardDictionaryConfigurationModel> GetSeekStandardDictionaryConfigurationItem(Guid Id)
        {
            return await dbContext.StandardDictionaryConfiguration.FirstOrDefaultAsync(a => a.Id == Id);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="appType"></param>
        /// <param name="pageNum"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<(List<GeneralConfigurationDto> data, int count)> GetGeneralConfigList(Guid parentId,string appType, int pageNum = 1, int pageSize = 10)
        {
            var list = await dbContext.GeneralConfiguration.Where(p => p.ParentId == parentId && p.AppType == appType).ToListAsync();
            var count = list.Count;
            var data = list.OrderByDescending(p => p.CreaterTime)
                .Skip(pageSize * (pageNum - 1))
                .Take(pageSize)
                .ToList();
            return (data, count);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="parentCode"></param>
        /// <returns></returns>
        public async Task<List<GeneralConfigurationDto>> GetGeneralConfigListByCode(string parentCode)
        {
            var data = from dict1 in dbContext.StandardDictionaryConfiguration
                       join dict2 in dbContext.GeneralConfiguration on dict1.Id equals dict2.ParentId
                       where parentCode.Equals(dict1.Code)
                       orderby dict2.CreaterTime 
                       select dict2;
            return await data.ToListAsync();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<GeneralConfigurationDto> AddGeneralConfigItem(GeneralConfigurationDto model)
        {
            dbContext.Set<GeneralConfigurationDto>().AddOrUpdate(t => t.SysId, model);
            await dbContext.SaveChangesAsync();
            return model;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<int> DelGeneralConfigItem(Guid key)
        {
            var data = await dbContext.GeneralConfiguration.FirstAsync(p => p.SysId == key);
            logger.LogWarning("DelGeneralConfigItem", JsonSerializer.Serialize(data));
            var modifiedEntity = dbContext.Entry(data);
            modifiedEntity.State = EntityState.Deleted;
            return await dbContext.SaveChangesAsync();
        }

    }
}
